#ifndef _QSAFEMAP_H
#define _QSAFEMAP_H

#include <QMap>
#include <QMutex>
#include <QMutexLocker>

template <class _Key, class _Value>
class QSafeMap
{
public:
	typedef typename QMap<_Key, _Value>::iterator iterator;
	typedef typename QMap<_Key, _Value>::const_iterator const_iterator;
	inline QSafeMap(): m(new QMutex(QMutex::Recursive))
	{
	}
	inline QSafeMap(const QSafeMap & _other): m(new QMutex(QMutex::Recursive))
	{
		QMutexLocker _locker_other(_other->m);
		q_map.unite(_other.q_map);
	}
	inline QSafeMap & operator = (const QSafeMap & _other)
	{
		QMutexLocker _locker_other(_other->m);
		QMutexLocker _locker(m);
		if (this != & _other)
		{
			q_map.clear();
			q_map.unite(_other.q_map);
		}
		return (* this);
	}
	inline ~QSafeMap()
	{
		delete m;
	}
	inline QMap<_Key, _Value> & map()
	{
		return (q_map);
	}
	inline const QMap<_Key, _Value> & map() const
	{
		return (q_map);
	}
	inline _Value & operator [] (const _Key & _key)
	{
		QMutexLocker _locker(m);
		return (q_map[_key]);
	}
	inline const _Value & operator [] (const _Key & _key) const
	{
		QMutexLocker _locker(m);
		return (q_map[_key]);
	}
	inline bool contains(const _Key & _key) const
	{
		QMutexLocker _locker(m);
		return (q_map.contains(_key));
	}
	inline QMap<_Key, _Value> copy() const
	{
		QMutexLocker _locker(m);
		return (QMap<_Key, _Value>().unite(q_map));
	}
	inline bool isEmpty() const
	{
		QMutexLocker _locker(m);
		return (q_map.isEmpty());
	}
	inline iterator find(const _Key & _key)
	{
		QMutexLocker _locker(m);
		return (q_map.find(_key));
	}
	inline iterator erase(const iterator & _i)
	{
		QMutexLocker _locker(m);
		return (q_map.erase(_i));
	}
	inline bool remove(const _Key & _key)
	{
		QMutexLocker _locker(m);
		return (q_map.remove(_key));
	}
	inline iterator begin()
	{
		QMutexLocker _locker(m);
		iterator _i = q_map.begin();
		return (_i);
	}
	inline const_iterator begin() const
	{
		QMutexLocker _locker(m);
		const_iterator _i = q_map.begin();
		return (_i);
	}
	inline iterator end()
	{
		QMutexLocker _locker(m);
		iterator _i = q_map.end();
		return (_i);
	}
	inline const_iterator end() const
	{
		QMutexLocker _locker(m);
		const_iterator _i = q_map.end();
		return (_i);
	}
	inline iterator at(int _i)
	{
		return (begin() + _i);
	}
	inline const_iterator at(int _i) const
	{
		return (begin() + _i);
	}
	inline iterator next(int & _i)
	{
		_i++;
		return (at(_i));
	}
	inline const_iterator next(int & _i) const
	{
		_i++;
		return (at(_i));
	}
	inline void clear()
	{
		QMutexLocker _locker(m);
		q_map.clear();
	}
	inline int count() const
	{
		QMutexLocker _locker(m);
		return (q_map.count());
	}
	inline QList<_Key> keys() const
	{
		QMutexLocker _locker(m);
		return (q_map.keys());
	}
	inline QList<_Value> values() const
	{
		QMutexLocker _locker(m);
		return (q_map.values());
	}
	inline QSafeMap<_Key, _Value> & unite(const QSafeMap<_Key, _Value> & _other)
	{
		QMutexLocker _locker(m);
		q_map.unite(_other.q_map);
		return (* this);
	}
	inline QSafeMap<_Key, _Value> & unite(const QMap<_Key, _Value> & _other)
	{
		QMutexLocker _locker(m);
		q_map.unite(_other);
		return (* this);
	}
private:
	QMap<_Key, _Value> q_map;
	mutable QMutex * m;
};

#endif